﻿using System;
using System.Text;

namespace PokemonTools.Entity
{
    public class Bytebuffer
    {
        public bool IsErrr { get; set; }

        public Byte[] Data { get; set; }
        public bool IsHttp { get; set; }

        private Byte[] _PackArray;
        private int _RIdx;
        private int _WIdx;

        public short ActionId { get; set; }

        public Bytebuffer(bool isHttp)
        {
            Data = new Byte[1024 * 1024];
            _PackArray = new Byte[1024 * 1024];
            _RIdx = 0;
            _WIdx = 0;
            IsHttp = isHttp;
        }

        public void Reset()
        {
            _RIdx = 0;
            _WIdx = 0;
        }

        public void ReadHead()
        {
            int tmpRIdx = 0;
            int tmpWIdx = 0;
            while (true)
            {
                this.ActionId = (short)((Data[1 + tmpRIdx] & 0xff) << 8 | Data[tmpRIdx] & 0xff); tmpRIdx += 2;
                short length = (short)((Data[1 + tmpRIdx] & 0xff) << 8 | Data[tmpRIdx] & 0xff); tmpRIdx += 2;
                byte status = 0;
                if (!IsHttp)
                {
                    status = Data[tmpRIdx++];
                }

                for (int i = 0; i < length; i++)
                {
                    _PackArray[tmpWIdx++] = Data[tmpRIdx++];
                }

                if (IsHttp)
                {
                    this.IsErrr = ActionId <= 0;
                    break;
                }
                else
                {
                    this.IsErrr = status == 2;
                }

                if (status != 1)
                    break;
            }
        }

        public Byte[] GetPostArray()
        {
            Byte[] array = new Byte[_WIdx + 4];
            BitConverter.GetBytes(Convert.ToInt16(ActionId)).CopyTo(array, 0);
            BitConverter.GetBytes(Convert.ToInt16(_WIdx)).CopyTo(array, 2);

            Buffer.BlockCopy(_PackArray, 0, array, 4, _WIdx);
            return array;
        }

        public byte ReadByte()
        {
            byte value = _PackArray[_RIdx];
            _RIdx++;
            return value;
        }
        public short ReadShort()
        {
            short value = (short)((_PackArray[1 + _RIdx] & 0xff) << 8 | _PackArray[_RIdx] & 0xff);
            _RIdx += 2;
            return value;
        }
        public int ReadInt()
        {
            int value = (_PackArray[3 + _RIdx] & 0xff) << 24 | (_PackArray[2 + _RIdx] & 0xff) << 16 | (_PackArray[1 + _RIdx] & 0xff) << 8 | _PackArray[_RIdx] & 0xff;
            _RIdx += 4;
            return value;
        }
        private String GetString(byte[] abyte0)
        {
            if (abyte0 == null)
                return "";
            int i = abyte0.Length;
            if (i == 0 || abyte0.Length % 2 != 0)
                return "";
            StringBuilder stringbuffer = new StringBuilder(i / 2);
            for (int j = 0; j < i; j += 2)
            {
                char c = (char)(abyte0[j] & 0xff | (abyte0[j + 1] & 0xff) << 8);
                stringbuffer.Append(c);
            }
            return stringbuffer.ToString();
        }
        public string ReadString()
        {
            short strLength = ReadShort();

            byte[] strData = new byte[strLength];
            for (short i = 0; i < strLength; i++)
                strData[i] = _PackArray[_RIdx + i];

            string value = GetString(strData);
            _RIdx += strLength;
            return value;
        }

        public void WriteByte(Byte value)
        {
            _PackArray[_WIdx++] = value;
        }
        public void WriteShort(Int16 value)
        {
            BitConverter.GetBytes(value).CopyTo(_PackArray, _WIdx);
            _WIdx += 2;
        }
        public void WriteInt(Int32 value)
        {
            BitConverter.GetBytes(value).CopyTo(_PackArray, _WIdx);
            _WIdx += 4;
        }
        public void WriteString(String value)
        {
            Byte[] outputStream = Encoding.Unicode.GetBytes(value);
            WriteShort((Int16)outputStream.Length);
            if (outputStream.Length > 0)
            {
                outputStream.CopyTo(_PackArray, _WIdx);
                _WIdx += outputStream.Length;
            }
        }
    }
}
